var ipRegular = "^(\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5]))\.(\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5]))\.(\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5]))\.(\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5]))$";


angular.module('CvirtDirectives', ['CvirtUtils', 'CvirtContextMenu']).
    directive('searchtree', function ($q, $http, $location, $templateCache, ContextMenu, $pollingPool, VM, $filter) {

        var show_context_menu = function (e, tree_id, tree_node) {
            ztree.selectNode(tree_node);
            var context_menu = ContextMenu.find_context_menu(tree_node.url);
            context_menu.css({"top": e.clientY + "px", "left": e.clientX + "px", "visibility": "visible"});
            $("body").bind("mousedown", ContextMenu.body_mousedown);
        };

        var ztree = null, _settings = {
            callback: {
                onRightClick: show_context_menu
            }
        };
        return {
            restrict: 'E',
            transclude: true,

            link: function (scope, element, attrs) {
                var _tree = element.find("#search-tree");
                $http.get(attrs.url).success(function (data, status, headers, config) {
                    scope.data = data;
                    ztree = $.fn.zTree.init(_tree, _settings, scope.data);
                    var re = new RegExp("^#" + $location.path() + "$", "gi");
                    var node = ztree.getNodesByFilter(function (node) {
                        return (node.url && re.test(node.url));
                    }, true);
                    ztree.selectNode(node);
                }).error(function (data, status, headers, config) {
                        scope.data = []
                    });

            },
            template:'<ul id="search-tree" class="ztree" ng-transclude></ul>'

        };
    })
    .directive('hosttoplist', function ($q, $http, $timeout, $pollingPool, $templateCache, $compile) {
        return {
            restrict: 'E',
            scope: {
                url: '@'
            },
            transclude: true,
            link: function (scope, element, attrs) {
                function load() {
                    //directive初始化时url中的id还没有渲染，请求后台会报错
                    if (scope.url.indexOf('//') == -1) {
                        $http.get(scope.url).success(function (data) {
                            scope.tops = data;
                        });
                    }

                }

                scope.$watch('url', function (url) {
                    load();
                })
                $pollingPool.add(function () {
                    load();
                }, 10000);
            },
            templateUrl: '/static/partials/shared/_top_hosts.html'
        };
    })
    .directive('vmtoplist', function ($q, $http, $timeout, $pollingPool, $templateCache, $compile) {
        return {
            restrict: 'E',
            scope: {
                url: '@'
            },
            transclude: true,
            link: function (scope, element, attrs) {

                function load() {
                    if (scope.url.indexOf('//') == -1) {
                        $http.get(scope.url).success(function (data) {
                            scope.tops = data;
                        });
                    }
                }

                scope.$watch('url', function (url) {
                    load();
                })
                $pollingPool.add(function () {
                    load();
                }, 10000);

            },
            templateUrl: '/static/partials/shared/_top_vms.html'
        };
    })
    .directive('piechart', function ($q) {
        return {
            restrict: 'E',
            scope: {
                initial: '=',
                width: '@',
                height: '@',
                title: '@'
            },
            transclude: true,
            link: function (scope, element, attrs) {
                var draw_pie_chart = function (data) {
                    element.find(".chart").highcharts({
                        credits: {
                            enabled: false
                        },
                        chart: {
                            plotBackgroundColor: null,
                            plotBorderWidth: null,
                            plotShadow: false
                        },
                        title: {
                            text: attrs.title
                        },
                        tooltip: {
                            formatter: function () {
                                return '<b>' + this.point.name + '</b>: ' + this.point.y + '<br />' + this.percentage.toFixed(2) + '%';
                            }
                        },
                        plotOptions: {
                            pie: {
                                allowPointSelect: true,
                                cursor: 'pointer',
                                dataLabels: {
                                    distance: -30,
                                    color: 'white'
//                                enabled: false
                                }
//                            showInLegend: true
                            }
                        },
                        series: [
                            {
                                type: 'pie',
                                name: 'OS share',
                                data: data
                            }
                        ]
                    });
                };

                function isEmptyObject(obj) {

                    for (var name in obj) {
                        return false;//因__proto__无法获取故无属性可轮循
                    }
                    return true;
                }

                scope.$watch('initial', function (new_value, old_value) {
                    if (new_value != undefined && new_value != null && new_value != '' && !isEmptyObject(new_value)) {
                        var data = [];
                        angular.forEach(new_value, function (val, key) {
                            data.push([key, val]);
                        });
                        draw_pie_chart(data);
                    } else {
                        draw_pie_chart([
                            ['unkown', 1]
                        ])
                    }
                });
            },
            template: '<div>'
                + '<div class="chart" width="{{width}}" height="{{height}}" style="min-width:{{width}}px; height:{{height}}px"></div>'
                + '<div class="hide" ng-transclude></div>'
                + '</div>'
        };
    })
    .directive('curvegraph', function ($q, $http, $timeout, $pollingPool, $filter) {
        return {
            restrict: 'E',
            scope: {
                name: "@",
                suffix: "@",
                title: '@',
                url: '@',
                width: '@',
                height: '@',
                max: '@',
                min: '@',
                serienum: '@'
            },
            link: function (scope, element, attrs) {
                var seriesnam1 = attrs.seriesnam1, seriesnam2 = attrs.seriesnam2;
                scope.serienum = parseInt(attrs.serienum);
                var line_datas1 = [], line_datas2 = [];
                for (var i = 0; i < 10; i++) {
                    line_datas1.push(["00:00:00", 50]);
                    if (scope.serienum > 1) {
                        line_datas2.push(["00:00:00", 60]);
                    }

                }

                var deferred = $q.defer();

                scope.$watch('url', function (new_value, old_value) {
                    if (new_value != undefined) {
                        deferred.resolve();
                    }
                });

                var options = {
                    credits: {
                        enabled: false
                    },
                    chart: {
                        type: 'spline',
                        renderTo: element.find('.graph')[0]
                    },
                    title: {
                        align: 'left'
                    },
                    subtitle: null,
                    xAxis: {
                        type: 'time',
                    },
                    yAxis: {
                        title: null,
                    },
                    rangeSelector: {
                        selected: 100
                    },
                    tooltip: {
                        valueSuffix: ''
                    },
                    plotOptions: {
                        spline: {
                            marker: {
                                enabled: false
                            }
                        }
                    },
                    tooltip: {
                        formatter: function () {
                            var format = this.y + "%";
                            if (seriesnam1 != 'cpu') {
                                format = $filter('bytes')(this.y)
                            }
                            return '<b>' + this.series.name + '</b>:' + format;

                        }
                    },
                    series: [
                        {
                            color: '#006900',
                            showInLegend: true,
                            name: seriesnam1,
                            data: []
                        }
                    ]
                };
                deferred.promise.then(function () {
                    options.yAxis.min = scope.min || 0;
//                options.yAxis.max = scope.max || 100;
                    if (scope.title) {
                        options.title.text = scope.title;
                    }
                    if (scope.serienum > 1) {
                        options.series.push({
                            color: '#FFC774',
                            showInLegend: true,
                            name: seriesnam2,
                            data: []
                        })
                    }
                    options.tooltip.valueSuffix = scope.suffix;
                    var highcharts = new Highcharts.Chart(options);
                    highcharts.series[0].setData(line_datas1);
                    if (scope.serienum > 1) highcharts.series[1].setData(line_datas2);
//                if(job) job.cancel();
                    $pollingPool.add(function () {
                        $http.get(attrs.url).success(function (data) {
                            line_datas1.shift();
                            line_datas1.push(data.line1);
                            highcharts.series[0].setData(line_datas1);
                            if (scope.serienum > 1) {
                                line_datas2.shift();
                                line_datas2.push(data.line2);
                                highcharts.series[1].setData(line_datas2);
                            }
                        });
                    }, 3000);
                });


            },
            template: '<div class="graph" width="{{width}}" height="{{height}}" style="width:{{width}}px; height:{{height}}px"></div>'
        };
    })
    .directive('selectable', function () {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                var fn;
//            element.find('input[type="checkbox"]').on('click', function(e){
//                e.preventDefault();
//            });
                scope.selected || (scope.$parent.selected = {}); //The selected collection must defined in parent scope first.
                element.on('click', function (e) {
                    element.closest('tbody').find('td').removeClass('selected');
                    element.find('td').addClass('selected');
                    if (attrs.selectable != '') {
                        if (attrs.exclusive != undefined) {
                            fn = function () {
                                angular.forEach(scope.selected, function (value, key) {
                                    scope.selected[key] = false;
                                });
                                scope.selected[scope[attrs.selectable].id] = true;
                            };
                        }
//                    else{
//                        fn = function(){
//                            if(e.target.nodeName != 'INPUT'){
//                                scope.selected[scope[attrs.selectable].id] = !scope.selected[scope[attrs.selectable].id];
//                            }
//                        };
//                    }
                        scope.$apply(fn);
                    }
                });
            }
        };
    })
    .directive('ipcheck',function () {

        return {
            require: 'ngModel',
            link: function (scope, elm, attrs, ctrl) {

                ctrl.$parsers.push(function (viewValue) {

                    var ipRE = new RegExp(ipRegular);
                    var pattern = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/g;

                    if (viewValue == "" || viewValue == undefined) {

                        ctrl.$setValidity('ipcheck', true);
                        return viewValue;
                    }

                    if (pattern.test(viewValue)) {

                        ctrl.$setValidity('ipcheck', true);
                        return viewValue;
                    } else {


                        ctrl.$setValidity('ipcheck', false);
                        return undefined;
                    }
                });
            }
        }

    }).directive('interfaceui',function ($q) {
        return {
            restrict: 'E',
            scope: {
                model: '=',
                index: '@',

            },
            transclude: true,
            link: function (scope, element, attrs) {

                scope.interface = scope.model;
                scope.index = attrs.index;

            },
            templateUrl: "/static/partials/vms/_interface.html"
        };
    }).directive('bootorder',function () {
        function get_bootorder(boot, items, scope) {
            var selected = $.grep(items, function (e) {
                return !$(e).hasClass('ui-state-disabled')
            })
            selected = $.map(selected, function (item) {
                return item.id;
            })
            scope.vm.bootorder = $.grep(boot.sortable('toArray'),function (item) {
                return selected.indexOf(item) != -1;
            }).join(',');
            console.log(scope.vm.bootorder);
        }

        return {
            restrict: 'E',
            link: function (scope, element, attrs) {
                //启动顺序
                var boot = element.find("#bootorder");
                if (scope.vm.bootorder) {
                    var orders = scope.vm.bootorder.split(',');
                    angular.forEach(orders, function (item) {
                        if (item == 'hd') {
                            name = '硬盘';
                        }
                        if (item == 'cdrom') {
                            name = '光驱';
                        }
                        if (item == 'network') {
                            name = '网络';
                        }
                        boot.append('<li id="' + item + '" class="ui-state-default"><input type="checkbox" checked="checked">' + name + '</li>')
                    })

                    //添加未激活的
                    if (orders.indexOf('hd') == -1) {
                        boot.append('<li id="hd" class="ui-state-default ui-state-disabled"><input type="checkbox">硬盘</li>');
                    }
                    if (orders.indexOf('cdrom') == -1) {
                        boot.append('<li id="cdrom" class="ui-state-default ui-state-disabled"><input type="checkbox">光驱</li>');
                    }
                    if (orders.indexOf('network') == -1) {
                        boot.append('<li id="network" class="ui-state-default ui-state-disabled"><input type="checkbox">网络</li>');
                    }

                }

                //应用拖动
                boot.sortable({
                    cancel: ".ui-state-disabled"
                });
                var items = element.find("#bootorder li");
                //禁止选中
                items.disableSelection();

                //checkbox选中和取消拖动效果
                element.find('#bootorder input:checkbox').click(function (e) {
                    var li = $(this).parent();
                    li.addClass('ui-state-disabled');
                    if ($(this).is(":checked")) {
                        li.removeClass('ui-state-disabled');
                    }
                    get_bootorder(boot, items, scope);
                });

                boot.on("sortstop", function (event, ui) {
                    get_bootorder(boot, items, scope);
                });
            },
            template: '<ul id="bootorder" class="span6"></ul>'
        };
    }).directive('mselect',function ($q, SecurityGroup) {
        return {
            restrict: 'E',
            link: function (scope, element, attrs) {
                scope.interface = scope.model;
                //FIXME 写死interface.securitygroups不好复用
                scope.interface.selectedgroup = $.map(scope.interface.securitygroups, function (item) {
                    return item.id;
                })
                var mselect;
                SecurityGroup.list({scope: 'all'}, function (data) {
                    angular.forEach(data.data, function (item) {
                        if (scope.interface.selectedgroup.indexOf(item.id) == -1) {//如果已经关联的要排除掉
                            element.append("<option value='" + item.id + "'>" + item.name + "</option>");
                        }
                    })
                    angular.forEach(scope.interface.securitygroups, function (item) {
                        element.append("<option value='" + item.id + "' selected>" + item.name + "</option>");
                    })

                    mselect = element.multiSelect({
                        selectableHeader: "<div class='custom-header'>安全规则</div>",
                        selectionHeader: "<div class='custom-header'>已关联</div>",
                        afterSelect: function (values) {
                            scope.interface.selectedgroup.push(parseInt(values[0]));
                            console.log(scope.interface.selectedgroup);
                        },
                        afterDeselect: function (values) {
                            scope.interface.selectedgroup.remove(parseInt(values[0]));
                            console.log(scope.interface.selectedgroup);
                        },
                    });
                })

            },
            template: '<select id="sgroupselect" multiple="multiple" name="my-select[]"></select>'
        };
    }).directive('tableorder',function ($filter) {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
//            var model = attrs.tableorder;
                var ths = element.find('th[by]');
                angular.forEach(ths, function (item) {
                    //加入鼠标样式(小手)
                    $(item).on('mouseover', function () {
                        this.style.cursor = 'pointer';
                    })
                    $(item).on('click', function (e) {
                        scope.orderfield = $(this).attr('by');
                        scope.reverse = !scope.reverse;
                        ths.find('img').remove();
                        var img = scope.reverse ? 'desc' : 'asc'
                        $(item).append('<img src="/static/images/sort_' + img + '.png"/>')
//                    if(model!=''){
//                        scope[model] = $filter('orderBy')(scope[model],scope.orderfield,scope.reverse);
//                    }
                    });
                })

            }

        };
    }).directive('pickdate',function ($q, SecurityGroup) {
        return {
            restrict: 'E',
            link: function (scope, element, attrs) {
                element.on('click', function (e) {
                    WdatePicker({el: 'valid_time', dateFmt: 'yyyy-MM-dd HH:mm:ss', onpicked: function () {
                        scope.event.start = $dp.cal.getDateStr();
                    }});
                })
            },
            template: '<img src="/static/vendor/DatePicker/skin/datePicker.gif" align="absmiddle">'
        };

    }).directive('fallback',function () {
        //为img标签增加默认图片
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                element.bind('error', function () {
                    angular.element(this).attr("src", attrs.fallback);
                });
            }
        };

    }).directive('ethiplist',function ($filter) {
        //虚拟机网卡ip视图
        return {
            restrict: 'E',
            scope: {
                interfaces: '='
            },
            link: function (scope, element, attrs) {

                scope.$watch('interfaces', function (interfaces) {
                    if (interfaces) {
                        var iplist = [];
                        angular.forEach(scope.interfaces, function (iface) {
                            if (iface.enable) {

                                if ((iface.network.networktype == 2 || iface.network.networktype == 3)
                                    && iface.network.rundhcp && iface.fixedip) {//ip自动选择则显示网络类型，因为这个时候还得不到fixedip
                                    //启用了dhcp才显示，防止网络修改后，fixedip没有删除，还是显示fixedip的问题
                                    iplist.push(iface.name + " : " + iface.fixedip.address);
                                } else {
                                    iplist.push(iface.name + " : " + $filter('network_type')(iface.network.networktype));
                                }
                            }
                        })
                        element.html(iplist.join('<br>'));
                    }
                })

            }
        };

    }).directive('treesearch', function (DataCenter,$location) {
        return {
            restrict: 'E',
            link: function (scope, element, attrs) {
                scope.classname = 'tcloud-search';
                var tags = element.find('#tags').autocomplete({
                    source: function (request, response) {
                        scope.classname = 'tcloud-search search_load';
                        DataCenter.q({term:request.term},function(data){
                            response(data);
                            scope.classname = 'tcloud-search';
                        },function(e){
                            scope.classname = 'tcloud-search';
                        })
                    },
                    select: function (event, ui) {
//                        $location.path(ui.item.url);
                        window.location.href = ui.item.url;
                    }
                })
                tags.data("uiAutocomplete")._renderItem = function (ul, item) {
                    return $("<li />")
                            .data("item.autocomplete", item)
                            .append("<a><img src='"+item.icon+"'/>" + item.label + "</a>")
                            .appendTo(ul);
                };
            },
            template:'<div class="input {{classname}}"><input type="text" id="tags" class="span12"></div>'
        };

    });
